﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;

namespace RPG_Helper
{
    class Personnage
    {
        public Personnage(string nom, Jeu jeu, int vie = 0, int mana = 0)
        {
            if(jeu.JeuCorrespondant == enumerations.Jeu.Autre) m_JeuDefini = false;
            else m_JeuDefini = true; // C'est un jeu existant, rien a modifier à l'affichage

            this.m_Nom = nom;
            this.m_Vie = vie; this.m_Mana = mana;
            this.m_ModificateurVie = 0; this.m_ModificateurMana = 0;
            this.m_caracteristique = new Dictionary<enumerations.caracteristique, int>();
            this.m_caracteristiqueModifiees = new Dictionary<enumerations.caracteristique, int>();

            this.m_ElementsAttaqueDefense = new Dictionary<enumerations.ElementNature, DefinitionElement>();
            this.m_ElementsAttaqueDefenseModifiees = new Dictionary<enumerations.ElementNature, DefinitionElement>();

            foreach(enumerations.caracteristique carac in jeu.caracteristiquesPresentes)
            { this.m_caracteristique.Add(carac, 0); this.m_caracteristiqueModifiees.Add(carac, 0); }

            foreach(enumerations.ElementNature elem in jeu.ElementsNaturePresent)
            { this.m_ElementsAttaqueDefense.Add(elem, new DefinitionElement()); this.m_ElementsAttaqueDefenseModifiees.Add(elem, new DefinitionElement()); }
            this.m_Equipements = new List<Equipement>();
        }

        public bool addNouvellecaract(enumerations.caracteristique nouvellecarac)
        {
            foreach(KeyValuePair<enumerations.caracteristique, int> carac in m_caracteristique)
                if(carac.Key.Equals(nouvellecarac)) return false;

            m_caracteristique.Add(nouvellecarac, 0);
            return true;
        }

        public void addPointscaract(enumerations.caracteristique carac)
        { 
            try { m_caracteristique[carac]++; } 
            catch(KeyNotFoundException ex) 
            { Console.WriteLine("caractéristique non trouvée : " + ex.Message); throw ex; } 
        }
        public bool addNouvelElement(enumerations.ElementNature nouvelElem)
        {
            foreach(KeyValuePair<enumerations.ElementNature, DefinitionElement> elem in m_ElementsAttaqueDefense)
                if(elem.Key.Equals(nouvelElem)) return false;

            m_ElementsAttaqueDefense.Add(nouvelElem, new DefinitionElement(0, 0));
            return true;
        }

        public void addEquipement(Equipement eq) { this.m_Equipements.Add(eq); }
        public void retirerEquipement(Equipement eq) { this.m_Equipements.Remove(eq); }

        public void MetAJourStat() 
        {
            // Réinitialisation des carractéristiques
            foreach(KeyValuePair<enumerations.caracteristique, int> valeur in this.m_caracteristique)
                this.m_caracteristiqueModifiees[valeur.Key] = 0;
            this.m_ModificateurVie = 0;
            this.m_ModificateurMana = 0;

            // Application des nouvelles carractéristiques
            foreach(Equipement eq in this.m_Equipements)
            {
                this.m_ModificateurVie += eq.getModifVie(this.m_Vie);
                this.m_ModificateurMana += eq.getModifMana(this.m_Mana);
                Dictionary<enumerations.caracteristique, int> modifs = eq.getModifications(this.m_caracteristique);
                foreach(KeyValuePair<enumerations.caracteristique, int> vals in modifs)
                    this.m_caracteristiqueModifiees[vals.Key] += vals.Value;
            }
        }

        #region Accesseur
        public string Nom { get { return this.m_Nom; } }
        public int Vie { get { return this.m_Vie + this.m_ModificateurVie; } set { this.m_Vie = value; } }
        public int Mana { get { return this.m_Mana + this.m_ModificateurMana; } set { this.m_Mana = value; } }
        public bool JeuDefini { get {return m_JeuDefini;} }

        public List<enumerations.caracteristique> caracteristiques
        { get { return m_caracteristique.Keys.ToList<enumerations.caracteristique>();  } }
        public List<enumerations.ElementNature> ElementsNature
        { get { return m_ElementsAttaqueDefense.Keys.ToList<enumerations.ElementNature>(); } }

        public List<Equipement> Equipements { get { return m_Equipements; } }

        public int pointsDe(enumerations.caracteristique carac) { return m_caracteristique[carac] + this.m_caracteristiqueModifiees[carac] ; }

        public int ResistanceA(enumerations.ElementNature elem)
        { return m_ElementsAttaqueDefense[elem].Resistance; }
        public int DegatsDe(enumerations.ElementNature elem)
        { return m_ElementsAttaqueDefense[elem].Attaque; }
        #endregion

        private bool m_JeuDefini;
        private string m_Nom;
        private int m_Vie; private int m_ModificateurVie;
        private int m_Mana; private int m_ModificateurMana;

        private List<Equipement> m_Equipements;

        // caracs de base
        private Dictionary<enumerations.caracteristique, int> m_caracteristique;
        private Dictionary<enumerations.ElementNature, DefinitionElement> m_ElementsAttaqueDefense;

        // Avec l'équipement
        private Dictionary<enumerations.caracteristique, int> m_caracteristiqueModifiees;
        private Dictionary<enumerations.ElementNature, DefinitionElement> m_ElementsAttaqueDefenseModifiees;
    };

    class DefinitionElement 
    { 
        public DefinitionElement(int attaque = 0, int resistance = 0) { this.m_Attaque = 0; this.m_Resistance = 0; } 
        public int Resistance { get {return this.m_Resistance; } set { this.m_Resistance = value; } }
        public int Attaque { get {return this.m_Attaque; } set { this.m_Attaque = value; } }
        private int m_Attaque;
        private int m_Resistance; 
    };
}
